home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-20 | 5.7 KB | 185 lines | [TEXT/CWIE] |
-
- #include "ThreadContext.h"
-
- #include "Exceptions.h"
-
- #if 0
- #if __MWERKS__
- extern void* __local_destructor_chain;
- #endif
- #endif
-
- //
- // Count of threads that have been created or are blocked
- // fCreatedThreads is counted by the TThreadContext constructor/destructor.
- // fSleepingThreads is counted by SwapIn/SwapOut (and fixed up by the destructor
- // if a sleeping thread is deleted)
- //
- long TThreadContext::fCreatedThreads = 0;
- long TThreadContext::fSleepingThreads = 0;
-
- TThreadContext::TThreadContext(long threadCreateRefcon) :
-
- #if 0
- fExceptionStack(nil),
- #if __MWERKS__
- fLocalDestructorChain(nil),
- #endif
- #endif
- fThreadCreateRefcon(threadCreateRefcon),
- fSleeping(false)
- {
- ++fCreatedThreads;
-
- // set up interface to C++ exception runtime support
- __new_exception_state(&fExceptionStack, fCatchBuffer, sizeof(fCatchBuffer));
- };
-
- //----------------------------------------------------------------------------------------
- // TThreadContext::SwapIn
- //----------------------------------------------------------------------------------------
- void TThreadContext::SwapIn(ThreadID /*threadID*/)
- {
-
- ExceptionState dummy;
- __switch_exception_state(&fExceptionStack, &dummy);
-
- #if 0
- gExceptionStack = fExceptionStack;
- #if __MWERKS__
- __local_destructor_chain = fLocalDestructorChain;
- #endif
- #endif
-
- //
- // If we were asleep at swapout time, then we
- // are awake now; adjust the sleeping thread count.
- //
- if(fSleeping)
- {
- fSleeping = false;
- --fSleepingThreads;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TThreadContext::SwapOut
- //----------------------------------------------------------------------------------------
- void TThreadContext::SwapOut(ThreadID threadID)
- {
- __switch_exception_state(&fExceptionStack, &fExceptionStack);
-
- #if 0
- fExceptionStack = gExceptionStack;
- #if __MWERKS__
- fLocalDestructorChain = __local_destructor_chain;
- #endif
- #endif
-
- ThreadState threadState;
- if(GetThreadState(threadID, &threadState) == noErr)
- {
- //
- // I'm not sure if the thread state is 'ready'
- // or 'running' in the swap out handler, but it's
- // probably 'ready'. Anyway, we assume that
- // 'stopped' is the only state a sleeping thread
- // will be in.
- //
- fSleeping = (threadState == kStoppedThreadState);
- if(fSleeping)
- {
- ++fSleepingThreads;
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TThreadContext::DisposeContext
- //----------------------------------------------------------------------------------------
- void TThreadContext::DisposeContext(ThreadID /*threadID*/)
- {
- delete this;
- }
-
- //----------------------------------------------------------------------------------------
- // SwapThreadContextIn
- //----------------------------------------------------------------------------------------
- pascal void SwapThreadContextIn(ThreadID thread, void* refCon)
- {
- TThreadContext* threadContext = (TThreadContext*) refCon;
- threadContext->SwapIn(thread);
- }
-
- //----------------------------------------------------------------------------------------
- // SwapThreadContextOut
- //----------------------------------------------------------------------------------------
- pascal void SwapThreadContextOut(ThreadID thread, void* refCon)
- {
- TThreadContext* threadContext = (TThreadContext*) refCon;
- threadContext->SwapOut(thread);
- }
-
- //----------------------------------------------------------------------------------------
- // DestroyThreadContext
- //----------------------------------------------------------------------------------------
- pascal void DestroyThreadContext(ThreadID thread, void* refCon)
- {
- TThreadContext* threadContext = (TThreadContext*) refCon;
- threadContext->DisposeContext(thread);
- }
-
- //----------------------------------------------------------------------------------------
- // ThreadCreateNotifyHandler
- //----------------------------------------------------------------------------------------
- pascal OSErr ThreadCreateNotifyHandler(ThreadID createdThread, long threadCreateRefcon)
- {
- TThreadContext* threadContext = new TThreadContext(threadCreateRefcon);
-
- SetThreadSwitcher(createdThread, SwapThreadContextIn, (void*) threadContext, true);
- SetThreadSwitcher(createdThread, SwapThreadContextOut, (void*) threadContext, false);
- SetThreadTerminator(createdThread, DestroyThreadContext, (void*) threadContext);
-
- return noErr;
- }
-
- //----------------------------------------------------------------------------------------
- // NewThreadWithNotification
- //
- // This routine calls 'NewThread', then notifies the application of what it has done
- //----------------------------------------------------------------------------------------
- OSErr NewThreadWithNotification(ThreadStyle threadStyle, ThreadEntryProcPtr threadEntry, void *threadParam, Size stackSize, ThreadOptions options, void **threadResult, ThreadID *threadMade, long threadCreateRefcon)
- {
- OSErr err = noErr;
-
- err = NewThread(threadStyle, threadEntry, threadParam, stackSize, options, threadResult, threadMade);
- if(err == noErr)
- err = ThreadCreateNotifyHandler(*threadMade, threadCreateRefcon);
-
- return err;
- }
-
- //----------------------------------------------------------------------------------------
- // ThreadCreateHandler
- //----------------------------------------------------------------------------------------
- pascal OSErr ThreadCreateHandler(ThreadEntryProcPtr threadEntry, void *threadParam, long handlerRefCon, ThreadID *threadMade)
- {
- Size stackSize = 0;
- ThreadOptions options = kCreateIfNeeded | kFPUNotNeeded;
-
- OSErr theErr = NewThread(
- kCooperativeThread,
- threadEntry,
- threadParam,
- stackSize,
- options,
- nil,
- threadMade);
-
- if(theErr == noErr)
- theErr = ThreadCreateNotifyHandler(*threadMade, handlerRefCon);
-
- return theErr;
- }
-
-